home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 3 / BBS in a box - Trilogy III.iso / Files / Prog / D-G / GemsII / radiosity / room.c < prev   
Encoding:
C/C++ Source or Header  |  1992-06-16  |  7.6 KB  |  234 lines  |  [TEXT/MPS ]

  1. /*****************************************************************************
  2. *     room.c 
  3. *
  4. *    This is a test program which constrcuts the Cornell radiosity room with 
  5. *   a ceiling light and two boxes inside. The side faces of the boxes are not 
  6. *    directly illuminated by the light. Therefore, they are a good example of 
  7. *    the color bleeding effects.
  8. *   This program calls IniRad(), DoRad() and CleanUpRad() in rad.c to perform 
  9. *    the radiosity rendering.
  10. *
  11. *    Copyright (C) 1990-1991 Apple Computer, Inc.
  12. *    All rights reserved.
  13. *
  14. *    12/1990 S. Eric Chen    
  15. ******************************************************************************/
  16.  
  17. #include "rad.h"
  18.  
  19. /* a quadrilateral */
  20. typedef struct {
  21.     short verts[4];    /* vertices of the quadrilateral */
  22.     short patchLevel; /* patch subdivision level (how fine to subdivide the quadrilateral?) */
  23.     short elementLevel; /* element subdivision level (how fine to subdivide a patch?) */
  24.     float area; /* area of the quadrilateral */
  25.     TVector3f normal; /* normal of the quadrilateral */
  26.     TSpectra* reflectance; /* diffuse reflectance of the quadrilateral */
  27.     TSpectra* emission; /* emission of the quadrilateral */
  28. } TQuad;
  29.  
  30. /* input parameters */
  31. TRadParams    params = {
  32.     0.001,            /* convergence threshold */
  33.     0, 0, 0, 0, 0, 0,    /* patches, elements and points; initialize these in InitParams */
  34.     {{ 108, 120, 400 },    /* camera location */
  35.     { 108, 100, 100 },    /* look at point */
  36.     { 0, 1, 0 },    /* up vector */
  37.     60, 60,            /* field of view in x, y*/
  38.     1, 550,            /* near, far */
  39.     200, 200,        /* resolution x, y */
  40.     0 },            /* buffer */
  41.     100,            /* hemi-cube resolution */
  42.     250,            /* approximate diameter of the room */
  43.     50,                /* intensity scale */
  44.     1                /* add the ambient term */
  45. };
  46.  
  47. TPoint3f roomPoints[] = {
  48.     0, 0, 0,
  49.     216, 0, 0,
  50.     216, 0, 215,
  51.     0, 0, 215,
  52.     0, 221, 0,
  53.     216, 221, 0,
  54.     216, 221, 215,
  55.     0, 221, 215,
  56.  
  57.     85.5, 220, 90,
  58.     130.5, 220, 90,
  59.     130.5, 220, 130,
  60.     85.5, 220, 130,
  61.  
  62.     53.104, 0, 64.104,
  63.     109.36, 0, 96.604,
  64.     76.896, 0, 152.896,
  65.     20.604, 0, 120.396,
  66.     53.104, 65, 64.104,
  67.     109.36, 65, 96.604,
  68.     76.896, 65, 152.896,
  69.     20.604, 65, 120.396,
  70.     
  71.     134.104, 0, 67.104,
  72.     190.396, 0, 99.604,
  73.     157.896, 0, 155.896,
  74.     101.604, 0, 123.396,
  75.     134.104, 130, 67.104,
  76.     190.396, 130, 99.604,
  77.     157.896, 130, 155.896,
  78.     101.604, 130, 123.396
  79. };
  80.  
  81. const TSpectra red = { 0.80, 0.10, 0.075 };
  82. const TSpectra yellow = { 0.9, 0.8, 0.1 };
  83. const TSpectra blue = { 0.075, 0.10, 0.35 };
  84. const TSpectra white = { 1.0, 1.0, 1.0 };
  85. const TSpectra lightGrey = { 0.9, 0.9, 0.9 };
  86. const TSpectra black = { 0.0, 0.0, 0.0 };
  87.  
  88. /* Assume a right-handed coordinate system */
  89. /* Polygon vertices follow counter-clockwise order when viewing from front */
  90. #define numberOfPolys     18
  91. TQuad roomPolys[numberOfPolys] = {
  92.     {{4, 5, 6, 7}, 2, 8, 216*215, {0, -1, 0}, &lightGrey, &black}, /* ceiling */
  93.     {{0, 3, 2, 1}, 3, 8, 216*215, {0, 1, 0}, &lightGrey, &black}, /* floor */
  94.     {{0, 4, 7, 3}, 2, 8, 221*215, {1, 0, 0}, &red, &black}, /* wall */
  95.     {{0, 1, 5, 4}, 2, 8, 221*216, {0, 0, 1}, &lightGrey, &black}, /* wall */
  96.     {{2, 6, 5, 1}, 2, 8, 221*215, {-1, 0, 0}, &blue, &black}, /* wall */
  97.     {{8, 9, 10, 11}, 2, 1, 40*45, {0, -1, 0}, &black, &white}, /* light */
  98.     {{16, 19, 18, 17}, 1, 5, 65*65, {0, 1, 0}, &yellow, &black}, /* box 1 */
  99.     {{12, 13, 14, 15}, 1, 1, 65*65, {0, -1, 0}, &yellow, &black},
  100.     {{12, 15, 19, 16}, 1, 5, 65*65, {-0.866, 0, -0.5}, &yellow, &black},
  101.     {{12, 16, 17, 13}, 1, 5, 65*65, {0.5, 0, -0.866}, &yellow, &black},
  102.     {{14, 13, 17, 18}, 1, 5, 65*65, {0.866, 0, 0.5}, &yellow, &black},
  103.     {{14, 18, 19, 15}, 1, 5, 65*65, {-0.5, 0, 0.866}, &yellow, &black},
  104.     {{24, 27, 26, 25}, 1, 5, 65*65, {0, 1, 0}, &lightGrey, &black}, /* box 2 */
  105.     {{20, 21, 22, 23}, 1, 1, 65*65, {0, -1, 0}, &lightGrey, &black},
  106.     {{20, 23, 27, 24}, 1, 6, 65*130, {-0.866, 0, -0.5}, &lightGrey, &black},
  107.     {{20, 24, 25, 21}, 1, 6, 65*130, {0.5, 0, -0.866}, &lightGrey, &black},
  108.     {{22, 21, 25, 26}, 1, 6, 65*130, {0.866, 0, 0.5}, &lightGrey, &black},
  109.     {{22, 26, 27, 23}, 1, 6, 65*130, {-0.5, 0, 0.866}, &lightGrey, &black},
  110. };
  111.  
  112.  
  113. /* Compute the xyz coordinates of a point on a quadrilateral given its u, v coordinates using bi-linear mapping */
  114. void UVToXYZ(const TPoint3f quad[4], float u, float v, TPoint3f* xyz)
  115. {
  116.     xyz->x = quad[0].x * (1-u)*(1-v) + quad[1].x * (1-u)*v + quad[2].x * u*v +             quad[3].x * u*(1-v);
  117.     xyz->y = quad[0].y * (1-u)*(1-v) + quad[1].y * (1-u)*v + quad[2].y * u*v +             quad[3].y * u*(1-v);
  118.     xyz->z = quad[0].z * (1-u)*(1-v) + quad[1].z * (1-u)*v + quad[2].z * u*v +             quad[3].z * u*(1-v);
  119. }
  120.  
  121. #define Index(i, j) ((i)*(nv+1)+(j))
  122.  
  123. int iOffset;     /* index offset to the point array */
  124. TPatch* pPatch;
  125. TElement* pElement;
  126. TPoint3f* pPoint;
  127.  
  128. /* Mesh a quarilateral into patches and elements */
  129. /* Output goes to pPatch, pElement, pPoint */
  130. void MeshQuad(TQuad* quad)
  131. {
  132.     TPoint3f pts[4];
  133.     int nu, nv;
  134.     double    du, dv;
  135.     int i, j;
  136.     double u, v;
  137.     int nPts=0;
  138.     float fi, fj;
  139.     int pi, pj;
  140.     
  141.     /* Calculate element vertices */
  142.     for (i=0; i<4; i++)
  143.         pts[i] = roomPoints[quad->verts[i]];
  144.     nu = nv = quad->patchLevel * quad->elementLevel+1;
  145.     du = 1.0 / (nu-1); dv = 1.0 / (nv-1);
  146.     for (i = 0, u = 0; i < nu; i++, u += du)
  147.         for (j = 0, v = 0; j < nv; j++, v += dv, nPts++)
  148.             UVToXYZ(pts, u, v, pPoint++);
  149.  
  150.     /* Calculate elements */
  151.     nu = nv = quad->patchLevel*quad->elementLevel;
  152.     du = 1.0 / nu; dv = 1.0 / nv;
  153.     for (i = 0, u = du/2.0; i < nu; i++, u += du)
  154.         for (j = 0, v = dv/2.0; j < nv; j++, v += dv, pElement++) {
  155.             pElement->normal = quad->normal;
  156.             pElement->nVerts = 4;
  157.             pElement->verts = (unsigned long*)calloc(4, sizeof(unsigned long));
  158.             pElement->verts[0] = Index(i, j)+iOffset;
  159.             pElement->verts[1] = Index(i+1, j)+iOffset;
  160.             pElement->verts[2] = Index(i+1, j+1)+iOffset;
  161.             pElement->verts[3] = Index(i, j+1)+iOffset;
  162.             pElement->area = quad->area / (nu*nv);
  163.             /* find out the parent patch */
  164.             fi = (float)i/(float)nu;
  165.             fj = (float)j/(float)nv;
  166.             pi = (int)(fi*(float)(quad->patchLevel));
  167.             pj = (int)(fj*(float)(quad->patchLevel));
  168.             pElement->patch = pPatch+pi*quad->patchLevel+pj;
  169.     }
  170.     
  171.     /* Calculate patches */
  172.     nu = quad->patchLevel; nv=quad->patchLevel;
  173.     du = 1.0 / nu; dv = 1.0 / nv;
  174.     for (i = 0, u = du/2.0; i < nu; i++, u += du)
  175.         for (j = 0, v = dv/2.0; j < nv; j++, v += dv, pPatch++) {
  176.             UVToXYZ(pts, u, v, &pPatch->center);
  177.             pPatch->normal = quad->normal;
  178.             pPatch->reflectance = quad->reflectance;
  179.             pPatch->emission = quad->emission;
  180.             pPatch->area = quad->area / (nu*nv);
  181.         }
  182.     
  183.     iOffset += nPts;
  184. }
  185.  
  186. /* Initialize input parameters */
  187. void InitParams()
  188. {
  189.     int i, n=0;
  190.  
  191.     /* compute the total number of patches */
  192.     params.nPatches=0;
  193.     for (i=numberOfPolys; i--; )
  194.         params.nPatches += roomPolys[i].patchLevel*roomPolys[i].patchLevel;
  195.     params.patches = (TPatch*)calloc(params.nPatches, sizeof(TPatch));
  196.  
  197.     /* compute the total number of elements */
  198.     params.nElements=0;
  199.     for (i=numberOfPolys; i--; )
  200.         params.nElements += roomPolys[i].elementLevel*roomPolys[i].patchLevel*
  201.                         roomPolys[i].elementLevel*roomPolys[i].patchLevel;
  202.     params.elements = (TElement*)calloc(params.nElements, sizeof(TElement));
  203.  
  204.     /* compute the total number of element vertices */
  205.     params.nPoints=0;
  206.     for (i=numberOfPolys; i--; )
  207.         params.nPoints += (roomPolys[i].elementLevel*roomPolys[i].patchLevel+1)*
  208.                         (roomPolys[i].elementLevel*roomPolys[i].patchLevel+1);
  209.     params.points = (TPoint3f*)calloc(params.nPoints, sizeof(TPoint3f));
  210.  
  211.     /* mesh the room to patches and elements */
  212.     iOffset = 0;
  213.     pPatch= params.patches;
  214.     pElement= params.elements;
  215.     pPoint= params.points;
  216.     for (i=0; i<numberOfPolys; i++)
  217.         MeshQuad(&roomPolys[i]);
  218.     
  219.     params.displayView.buffer= (unsigned long*)calloc(
  220.         params.displayView.xRes*params.displayView.yRes, sizeof(unsigned long));
  221.     params.displayView.wid=0;
  222. }
  223.  
  224. void main()
  225. {
  226.     InitParams();
  227.     InitRad(¶ms);
  228.     DoRad();
  229.     CleanUpRad();
  230. }
  231.  
  232.  
  233.  
  234.